package com.kk.my_pro.config.security;


import com.kk.my_pro.common.utility.jwt.JwtFilter;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
//
///**
// * 授权服务器（模仿springSecurity框架源码的OAuth2AuthorizationServerConfiguration这个类）
// */
@Configuration
@Order(2)
//@AllArgsConstructor


@EnableWebSecurity//开启springsecurity配置修改
public class WebSecurityConfig {
    public final static String[] ALLOW_PATH_PATTERNS = {"/systemUser/register","/systemUser/login"}; //定义无需认证授权得路径



    // springSecurity重要关注的类：UserDetailsService、AuthenticationManager、securityFilterChain



    @Resource
    DBUserDetailsManager userService;



    @Bean//PasswordEncoder的实现类为BCryptPasswordEncoder
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }





    @Bean
    public AuthenticationProvider authenticationProvider(){
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setPasswordEncoder(passwordEncoder());
        provider.setUserDetailsService(userService);
        return provider;
    }


    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception {
        return configuration.getAuthenticationManager();
    }




    @Resource
    JwtFilter jwtFilter;//

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.formLogin(AbstractHttpConfigurer::disable)//取消默认登录页面的使用
                .logout(AbstractHttpConfigurer::disable)//取消默认登出页面的使用
                .authenticationProvider(authenticationProvider())//将自己配置的PasswordEncoder放入SecurityFilterChain中
                .csrf(AbstractHttpConfigurer::disable)//禁用csrf保护，前后端分离不需要
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))//禁用session，因为我们已经使用了JWT
                .httpBasic(AbstractHttpConfigurer::disable)//禁用httpBasic，因为我们传输数据用的是post，而且请求体是JSON
                .authorizeHttpRequests(request -> request.requestMatchers(HttpMethod.POST, ALLOW_PATH_PATTERNS).permitAll().anyRequest().authenticated())//开放两个接口，一个注册，一个登录，其余均要身份认证
               .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);//将用户授权时用到的JWT校验过滤器添加进SecurityFilterChain中，并把自定义过滤器JwtFilter放在UsernamePasswordAuthenticationFilter过滤器的的前面
        return httpSecurity.build();
    }






//
//
//
//    /**
//     * springSecurity默认的过滤器链（可不写）
//     *
//     * @param http
//     * @return
//     * @throws Exception
//     */
//    @Bean
//    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
//        OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
//        RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
//        // 开启授权保护
//
//        http.authorizeHttpRequests(
//                        authorize -> authorize
//
////                                .requestMatchers("/user/list").hasAuthority("USER_LIST") // 接口user/list，只能由USER_LIST角色操作
////                                .requestMatchers("/user/add").hasAuthority("USER_ADD") // 接口user/add，只能由USER_ADD角色操作
//                                .requestMatchers("/systemUser/**").hasRole("ADMIN") // 该角色可以访问/user下所有接口
//                                .anyRequest() // 对所有请求开启授权保护
//                                .authenticated() // 已认证的请求会被自动授权
//
//                );
//
//        //关闭远古时期单体架构（前后不分离项目）的filter----表单登录---这些filter都是前后不分离的
//        http.formLogin(AbstractHttpConfigurer::disable)
//                .httpBasic(AbstractHttpConfigurer::disable)
//                        .logout(AbstractHttpConfigurer::disable)
//                                .sessionManagement(AbstractHttpConfigurer::disable)
//                                        .csrf(AbstractHttpConfigurer::disable)
//                                                .requestCache(cache->cache.requestCache(new NullRequestCache()))
//                                                        .anonymous(AbstractHttpConfigurer::disable);
//
//
//        // 插入自定义过滤链
//        http.addFilterBefore(new MyCustomFilter(), UsernamePasswordAuthenticationFilter.class);
//
//
//
////                .formLogin(form -> {
////                    form.successHandler(new MyAuthenticationSuccessHandler()) //认证成功时的处理
////                            .failureHandler(new MyAuthenticationFailureHandler())//认证失败时的处理
////                    ;
////                }); // 使用表单授权方式
//
//
////        http.logout(logout -> {
////            logout.logoutSuccessHandler(new MyLogoutSuccessHandler());//退出登录，注销成功时的处理
////        });
//
//
////
////        http.exceptionHandling(logout -> {
////            logout.authenticationEntryPoint(new MyAuthenticationEntryPoint());//请求未认证的处理
////        });
//        http.csrf(withDefaults()); // 允许跨越
//        //.httpBasic(withDefaults()); // 使用基本授权方式
//        http.csrf(csrf -> csrf.disable()); // 关闭csrf防御
//        return http.build();
//    }
//


}
